﻿using System;
using Tiny.Imaging.Filter.BaseFilter;
using Tiny.Imaging.Filter.ChannelBlendLibrary;
using Tiny.Imaging.Filter.PixelLibrary;

namespace Tiny.Imaging.Filter.PointFilter
{
    public class LayerBlendFilter : BaseFilter.BaseFilter
    {
        private readonly int[] _blendLayer;
        private int[][] _mapping;

        public LayerBlendFilter(int[] blendLayer, Func<int, int, int> blend, int opacity = 100)
            : base(blend, opacity)
        {
            _blendLayer = blendLayer;
            PrePopulate(blend, opacity);
        }

        private void PrePopulate(Func<int, int, int> blendFunc, int opacity = 100)
        {
            _mapping = new int[256][];
            for (int i = 0; i < 256; ++i)
            {
                _mapping[i] = new int[256];
                for (int j = 0; j < 256; ++j)
                {
                    _mapping[i][j] = Blend(i, j);
                }
            }
        }

        public override int[] Apply(int[] pixels)
        {
            var results = new int[pixels.Length];
            for (int i = 0; i < pixels.Length; ++i)
            {
                results[i] = Process(i, Rgba.Parse(pixels[i]));
            }

            return results;
        }

        public override int Process(Rgba rgba)
        {
            throw new NotImplementedException();
        }

        private int Process(int idx, Rgba baseColor)
        {
            Rgba blendColor = Rgba.Parse(_blendLayer[idx]);
            baseColor.R = _mapping[baseColor.R][blendColor.R];
            baseColor.G = _mapping[baseColor.G][blendColor.G];
            baseColor.B = _mapping[baseColor.B][blendColor.B];

            return baseColor.ToInteger();
        }
    }
}